package controllers

import command.CommandExec
import dao._
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}
import tool.{FormTool, Tool}
import utils.Utils

import javax.inject.Inject
import scala.concurrent.ExecutionContext.Implicits.global
import implicits.Implicits._
import shared.VarTool
import tool.Pojo.CommandData

import java.io.File

/**
 * Created by yz on 7/5/2021
 */
class CircRnaController @Inject()(cc: ControllerComponents)(
  implicit val browseCircRnaDao: BrowseCircRnaDao,
  implicit val detailCircRnaDao: DetailCircRnaDao,
  implicit val modeDao: ModeDao,
) extends AbstractController(cc) {

  val kind=VarTool.circRnaKind

  def searchAllByGeneSymbolOrId: Action[AnyContent] = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    val id = data.id
    val ids = id.split(",").map(_.trim).distinct
    browseCircRnaDao.selectAllByGeneSymbolOrId(ids).map { x =>
      val json = Utils.getJsonByTs(x)
      Ok(json)
    }
  }

  def toResultByPosition: Action[AnyContent] = Action.async { implicit request =>
    val data = FormTool.positionForm.bindFromRequest().get
    val kind = FormTool.kindForm.bindFromRequest().get.kind
    val circsF = browseCircRnaDao.selectByPosition(data.chr, data.start, data.end)
    circsF.map {
      x =>
        val id = x.map(_.circId).mkString(",")
        Ok(views.html.search.result(id, kind))
    }
  }

  def getAllCircIdAndGeneName: Action[AnyContent] = Action.async { implicit request =>
    browseCircRnaDao.selectAllGeneSymbol.zip(browseCircRnaDao.selectAllCircId) map { case (geneNames, circIds) =>
      val union = geneNames.concat(circIds).distinct
      Ok(Json.toJson(union))
    }
  }

  def toResultBySymbolOrId: Action[AnyContent] = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    val kind = FormTool.kindForm.bindFromRequest().get.kind
    val ids = data.id.split(",").map(_.trim).distinct
    val circsF = browseCircRnaDao.selectAllByGeneSymbol(ids).zip(browseCircRnaDao.selectByCircIds(ids))
    circsF.map { case (circs1, circs2) =>
      val finalId = (circs1 ::: circs2).map(_.circId).mkString(",")
      Ok(views.html.search.result(finalId, kind))
    }
  }

  def getDetail: Action[AnyContent] = Action.async { implicit request =>
    val data = FormTool.idForm.bindFromRequest().get
    val id = data.id
    detailCircRnaDao.selectById(id).map { x =>
      val json = x.myAsJson
      Ok(json)
    }
  }

  def getProfileImage = Action {
    implicit request =>
      val data = FormTool.profileForm.bindFromRequest().get
      val tmpDir = Tool.createTempDirectory("tmpDir")
      val pdfFile = new File(tmpDir, "out.pdf")
      val pngFile = new File(tmpDir, "out.png")
      val command =
        s"""
           |${"Rscript".condaPath()} ${Tool.rPath.unixPath}/detail_circRNA_boxplot1.R --t ${data.id} --i ${Tool.getTargetFile(kind,data.id).unixPath} --l ${data.logScale} --c '${data.kinds.mkString(",")}' --o ${pdfFile.unixPath}
           |convert  -density 300 -background white -alpha remove -alpha off ${pdfFile.getAbsoluteFile.unixPath} ${pngFile.getAbsoluteFile.unixPath}
           |""".stripMargin

      val commandExec = CommandExec().exec { b =>
        CommandData(tmpDir, command)
      }
      if (commandExec.isSuccess) {
        val base64 = pngFile.base64
        val pdfBase64 = pdfFile.base64
        Tool.deleteDirectory(tmpDir)
        Ok(Json.obj("valid" -> true, "base64" -> base64, "pdfBase64" -> pdfBase64))
      } else {
        Tool.deleteDirectory(tmpDir)
        Ok(Json.obj("valid" -> false, "message" -> commandExec.errorInfo))
      }
  }

  def getComparisonImage = Action {
    implicit request =>
      val data = FormTool.comparisonForm.bindFromRequest().get
      val tmpDir = Tool.createTempDirectory("tmpDir")
      val pdfFile = new File(tmpDir, "out.pdf")
      val pngFile = new File(tmpDir, "out.png")
      val cStr=List(data.kindA,data.kindB).mkString(",")
      val command =
        s"""
           |${"Rscript".condaPath()} ${Tool.rPath.unixPath}/detail_circRNA_boxplot2.R  --t ${data.id} --i ${Tool.getTargetFile(kind,data.id).unixPath} --l ${data.logScale} --m ${data.method} --c '${cStr}' --o ${pdfFile.unixPath}
           |convert  -density 300 -background white -alpha remove -alpha off ${pdfFile.getAbsoluteFile.unixPath} ${pngFile.getAbsoluteFile.unixPath}
           |""".stripMargin

      val commandExec = CommandExec().exec { b =>
        CommandData(tmpDir, command)
      }
      if (commandExec.isSuccess) {
        val base64 = pngFile.base64
        val pdfBase64 = pdfFile.base64
        Tool.deleteDirectory(tmpDir)
        Ok(Json.obj("valid" -> true, "base64" -> base64, "pdfBase64" -> pdfBase64))
      } else {
        Tool.deleteDirectory(tmpDir)
        Ok(Json.obj("valid" -> false, "message" -> commandExec.errorInfo))
      }
  }

  def searchAllByServer = Action.async { implicit request =>
    val data = FormTool.circRnaForm.bindFromRequest().get
    val pageData=FormTool.pageForm.bindFromRequest().get
    browseCircRnaDao.selectAll(data,pageData).map {case (size, x)=>
      val array=Utils.getJsonByTs(x)
      Ok(Json.obj("rows" -> array, "total" -> size))
    }
  }

  def downloadAll = Action.async { implicit request =>
    val ids = FormTool.idsForm.bindFromRequest().get.ids
    val tmpDir = Tool.createTempDirectory("tmpDir")
    val outFile = new File(tmpDir, "out.csv")
    browseCircRnaDao.selectAll(ids).map { xs =>
      xs.toList.lines.convertHeaderIgnoreCase(VarTool.circRnaMap).toFile(outFile)
      Ok.sendFile(outFile, onClose = () => {
        Tool.deleteDirectory(tmpDir)
      })
    }
  }

  def getAllDiffGroup = Action.async {
    browseCircRnaDao.selectAllDiffGroup.map { x =>
      val types = x.flatMap { x =>
        x.mySplit(",")
      }.map(_.trim).distinct.notEmptyLines.sorted
      val finalTypes = if (types.containsIgnoreCase("NA")) {
        types.find(_.equalsIgnoreCase("NA")).get :: types.filterNot(x => "NA".equalsIgnoreCase(x))
      } else types
      Ok(Json.toJson(finalTypes))
    }
  }




}
